﻿
#region Imported Namespaces

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Xml.Serialization;

#endregion

namespace TupleGeo.Emergency.CAP {

  /// <summary>
  /// <para>
  /// The container for all component parts of the info sub-element of the alert message.
  /// </para>
  /// <para>
  /// The info segment describes an anticipated or actual event in terms of:
  /// <list type="bullet">
  ///   <item>
  ///     <term>its urgency</term>
  ///     <description>(time available to prepare)</description>
  ///   </item>
  ///   <item>
  ///     <term>severity</term>
  ///     <description>(intensity of impact)</description>
  ///   </item>
  ///   <item>
  ///     <term>certainty</term>
  ///     <description>(confidence in the observation or prediction)</description>
  ///   </item>
  /// </list>
  /// as well as providing both categorical and textual descriptions of the subject event.
  /// </para>
  /// <para>
  /// It may also provide instructions for appropriate response by message recipients
  /// and various other details (hazard duration, technical parameters, contact information,
  /// links to additional information sources, etc.) Multiple info segments may be used
  /// to describe differing parameters (e.g., for different probability or intensity bands)
  /// or to provide the information in multiple languages.
  /// </para>
  /// </summary>
  /// <remarks>
  /// <para>Optional.</para>
  /// <para>
  /// Multiple occurrences are permitted within a single <see cref="Alert"/>.
  /// If targeting of multiple info blocks in the same language overlaps,
  /// information in later blocks may expand but may not override the
  /// corresponding values in earlier ones. Each set of info blocks
  /// containing the same language identifier SHALL be treated as a
  /// separate sequence. In addition to the specified subelements,
  /// MAY contain one or more <see cref="Resource"/> blocks and/or
  /// one or more <see cref="AlertInfoArea">area</see> blocks.
  /// </para>
  /// </remarks>
  [SerializableAttribute()]
  [DesignerCategoryAttribute("code")]
  [XmlTypeAttribute(TypeName = "alertInfo", AnonymousType = true, Namespace = "urn:oasis:names:tc:emergency:cap:1.2")]
  [DataContractAttribute(Name = "alertInfo", Namespace = "urn:oasis:names:tc:emergency:cap:1.2")]
  [TypeConverterAttribute(typeof(ExpandableObjectConverter))]
  public partial class AlertInfo : EntityBase<AlertInfo> {

    #region Constructors - Destructors

    /// <summary>
    /// Initializes the AlertInfo.
    /// </summary>
    public AlertInfo() {
      this._area = new List<AlertInfoArea>();
      this._resource = new List<AlertInfoResource>();
      this._parameter = new List<AlertInfoParameter>();
      this._eventCode = new List<AlertInfoEventCode>();
      this._responseType = new List<AlertInfoResponseType>();
      this._eventCategory = new List<AlertInfoCategory>();
      this._language = "en-US";
    }

    #endregion

    #region Public Properties

    private string _language;

    // TODO *** Should DataType = "language" or DataType = "Language" instead ???
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "language", DataType = "language", Order = 0)]
    [DefaultValueAttribute("en-US")]
    [DataMemberAttribute(Name = "language", Order = 0)]
    public virtual string Language {
      get {
        //TODO: na dw gia ti den mporw na ftiajw to language se Kefalaio.
        return this._language;
      }
      set {
        if ((this._language != null)) {
          if ((_language.Equals(value) != true)) {
            this._language = value;
            this.OnPropertyChanged("Language");
          }
        }
        else {
          this._language = value;
          this.OnPropertyChanged("Language");
        }
      }
    }

    private List<AlertInfoCategory> _eventCategory;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "category", Order = 1)]
    [DataMemberAttribute(Name = "category", Order = 1)]
    public virtual List<AlertInfoCategory> EventCategory {
      get {
        return this._eventCategory;
      }
      set {
        if ((this._eventCategory != null)) {
          if ((_eventCategory.Equals(value) != true)) {
            this._eventCategory = value;
            this.OnPropertyChanged("EventCategory");
          }
        }
        else {
          this._eventCategory = value;
          this.OnPropertyChanged("EventCategory");
        }
      }
    }

    private string _eventType;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "event", Order = 2)]
    [DataMemberAttribute(Name = "event", Order = 2)]
    public virtual string EventType {
      get {
        return this._eventType;
      }
      set {
        if ((this._eventType != null)) {
          if ((_eventType.Equals(value) != true)) {
            this._eventType = value;
            this.OnPropertyChanged("EventType");
          }
        }
        else {
          this._eventType = value;
          this.OnPropertyChanged("EventType");
        }
      }
    }

    private List<AlertInfoResponseType> _responseType;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "responseType", Order = 3)]
    [DataMemberAttribute(Name = "responseType", Order = 3)]
    public virtual List<AlertInfoResponseType> ResponseType {
      get {
        return this._responseType;
      }
      set {
        if ((this._responseType != null)) {
          if ((_responseType.Equals(value) != true)) {
            this._responseType = value;
            this.OnPropertyChanged("ResponseType");
          }
        }
        else {
          this._responseType = value;
          this.OnPropertyChanged("ResponseType");
        }
      }
    }

    private AlertInfoUrgency _urgency;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "urgency", Order = 4)]
    [DataMemberAttribute(Name = "urgency", Order = 4)]
    public virtual AlertInfoUrgency Urgency {
      get {
        return this._urgency;
      }
      set {
        if ((_urgency.Equals(value) != true)) {
          this._urgency = value;
          this.OnPropertyChanged("Urgency");
        }
      }
    }

    private AlertInfoSeverity _severity;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "severity", Order = 5)]
    [DataMemberAttribute(Name = "severity", Order = 5)]
    public virtual AlertInfoSeverity Severity {
      get {
        return this._severity;
      }
      set {
        if ((_severity.Equals(value) != true)) {
          this._severity = value;
          this.OnPropertyChanged("Severity");
        }
      }
    }

    private AlertInfoCertainty _certainty;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "certainty", Order = 6)]
    [DataMemberAttribute(Name = "certainty", Order = 6)]
    public virtual AlertInfoCertainty Certainty {
      get {
        return this._certainty;
      }
      set {
        if ((_certainty.Equals(value) != true)) {
          this._certainty = value;
          this.OnPropertyChanged("Certainty");
        }
      }
    }

    private string _audience;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "audience", Order = 7)]
    [DataMemberAttribute(Name = "audience", Order = 7)]
    public virtual string Audience {
      get {
        return this._audience;
      }
      set {
        if ((this._audience != null)) {
          if ((_audience.Equals(value) != true)) {
            this._audience = value;
            this.OnPropertyChanged("Audience");
          }
        }
        else {
          this._audience = value;
          this.OnPropertyChanged("Audience");
        }
      }
    }

    private List<AlertInfoEventCode> _eventCode;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "eventCode", Order = 8)]
    [DataMemberAttribute(Name = "eventCode", Order = 8)]
    public virtual List<AlertInfoEventCode> EventCode {
      get {
        return this._eventCode;
      }
      set {
        if ((this._eventCode != null)) {
          if ((_eventCode.Equals(value) != true)) {
            this._eventCode = value;
            this.OnPropertyChanged("EventCode");
          }
        }
        else {
          this._eventCode = value;
          this.OnPropertyChanged("EventCode");
        }
      }
    }

    private DateTime _effectiveDateTime;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "effective", Order = 9)]
    [DataMemberAttribute(Name = "effective", Order = 9)]
    public virtual DateTime EffectiveDateTime {
      get {
        return this._effectiveDateTime;
      }
      set {
        if ((_effectiveDateTime.Equals(value) != true)) {
          this._effectiveDateTime = value;
          this.OnPropertyChanged("EffectiveDateTime");
        }
      }
    }

    private bool _effectiveDateTimeSpecified;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlIgnoreAttribute()]
    [DataMemberAttribute(Name = "effectiveSpecified", Order = 10)]
    public virtual bool EffectiveDateTimeSpecified {
      get {
        return this._effectiveDateTimeSpecified;
      }
      set {
        if ((_effectiveDateTimeSpecified.Equals(value) != true)) {
          this._effectiveDateTimeSpecified = value;
          this.OnPropertyChanged("EffectiveDateTimeSpecified");
        }
      }
    }

    private DateTime _onsetDateTime;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "onset", Order = 10)]
    [DataMemberAttribute(Name = "onset", Order = 11)]
    public virtual DateTime OnsetDateTime {
      get {
        return this._onsetDateTime;
      }
      set {
        if ((_onsetDateTime.Equals(value) != true)) {
          this._onsetDateTime = value;
          this.OnPropertyChanged("OnsetDateTime");
        }
      }
    }

    private bool _onsetDateTimeSpecified;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlIgnoreAttribute()]
    [DataMemberAttribute(Name = "onsetSpecified", Order = 12)]
    public virtual bool OnsetDateTimeSpecified {
      get {
        return this._onsetDateTimeSpecified;
      }
      set {
        if ((_onsetDateTimeSpecified.Equals(value) != true)) {
          this._onsetDateTimeSpecified = value;
          this.OnPropertyChanged("OnsetDateTimeSpecified");
        }
      }
    }

    private DateTime _expirationDateTime;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "expires", Order = 11)]
    [DataMemberAttribute(Name = "expires", Order = 13)]
    public virtual DateTime ExpirationDateTime {
      get {
        return this._expirationDateTime;
      }
      set {
        if ((_expirationDateTime.Equals(value) != true)) {
          this._expirationDateTime = value;
          this.OnPropertyChanged("ExpirationDateTime");
        }
      }
    }

    private bool _expirationDateTimeSpecified;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlIgnoreAttribute()]
    [DataMemberAttribute(Name = "expiresSpecified", Order = 14)]
    public virtual bool ExpirationDateTimeSpecified {
      get {
        return this._expirationDateTimeSpecified;
      }
      set {
        if ((_expirationDateTimeSpecified.Equals(value) != true)) {
          this._expirationDateTimeSpecified = value;
          this.OnPropertyChanged("ExpirationDateTimeSpecified");
        }
      }
    }

    private string _senderName;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "senderName", Order = 12)]
    [DataMemberAttribute(Name = "senderName", Order = 15)]
    public virtual string SenderName {
      get {
        return this._senderName;
      }
      set {
        if ((this._senderName != null)) {
          if ((_senderName.Equals(value) != true)) {
            this._senderName = value;
            this.OnPropertyChanged("SenderName");
          }
        }
        else {
          this._senderName = value;
          this.OnPropertyChanged("SenderName");
        }
      }
    }

    private string _headline;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "headline", Order = 13)]
    [DataMemberAttribute(Name = "headline", Order = 16)]
    public virtual string Headline {
      get {
        return this._headline;
      }
      set {
        if ((this._headline != null)) {
          if ((_headline.Equals(value) != true)) {
            this._headline = value;
            this.OnPropertyChanged("Headline");
          }
        }
        else {
          this._headline = value;
          this.OnPropertyChanged("Headline");
        }
      }
    }

    private string _eventDescription;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "description", Order = 14)]
    [DataMemberAttribute(Name = "description", Order = 17)]
    public virtual string EventDescription {
      get {
        return this._eventDescription;
      }
      set {
        if ((this._eventDescription != null)) {
          if ((_eventDescription.Equals(value) != true)) {
            this._eventDescription = value;
            this.OnPropertyChanged("EventDescription");
          }
        }
        else {
          this._eventDescription = value;
          this.OnPropertyChanged("EventDescription");
        }
      }
    }

    private string _instructions;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "instruction", Order = 15)]
    [DataMemberAttribute(Name = "instruction", Order = 18)]
    public virtual string Instructions {
      get {
        return this._instructions;
      }
      set {
        if ((this._instructions != null)) {
          if ((_instructions.Equals(value) != true)) {
            this._instructions = value;
            this.OnPropertyChanged("Instructions");
          }
        }
        else {
          this._instructions = value;
          this.OnPropertyChanged("Instructions");
        }
      }
    }

    private string _informationUrl;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "web", DataType = "anyURI", Order = 16)]
    [DataMemberAttribute(Name = "web", Order = 19)]
    public virtual string InformationUrl {
      get {
        return this._informationUrl;
      }
      set {
        if ((this._informationUrl != null)) {
          if ((_informationUrl.Equals(value) != true)) {
            this._informationUrl = value;
            this.OnPropertyChanged("InformationUrl");
          }
        }
        else {
          this._informationUrl = value;
          this.OnPropertyChanged("InformationUrl");
        }
      }
    }
    
    private string _contactInfo;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "contact", Order = 17)]
    [DataMemberAttribute(Name = "contact", Order = 20)]
    public virtual string ContactInfo {
      get {
        return this._contactInfo;
      }
      set {
        if ((this._contactInfo != null)) {
          if ((_contactInfo.Equals(value) != true)) {
            this._contactInfo = value;
            this.OnPropertyChanged("ContactInfo");
          }
        }
        else {
          this._contactInfo = value;
          this.OnPropertyChanged("ContactInfo");
        }
      }
    }

    private List<AlertInfoParameter> _parameter;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "parameter", Order = 18)]
    [DataMemberAttribute(Name = "parameter", Order = 21)]
    public virtual List<AlertInfoParameter> Parameter {
      get {
        return this._parameter;
      }
      set {
        if ((this._parameter != null)) {
          if ((_parameter.Equals(value) != true)) {
            this._parameter = value;
            this.OnPropertyChanged("Parameter");
          }
        }
        else {
          this._parameter = value;
          this.OnPropertyChanged("Parameter");
        }
      }
    }

    private List<AlertInfoResource> _resource;
    
    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "resource", Order = 19)]
    [DataMemberAttribute(Name = "resource", Order = 22)]
    public virtual List<AlertInfoResource> Resource {
      get {
        return this._resource;
      }
      set {
        if ((this._resource != null)) {
          if ((_resource.Equals(value) != true)) {
            this._resource = value;
            this.OnPropertyChanged("Resource");
          }
        }
        else {
          this._resource = value;
          this.OnPropertyChanged("Resource");
        }
      }
    }

    private List<AlertInfoArea> _area;

    /// <summary>
    /// 
    /// </summary>
    [XmlElementAttribute(ElementName = "area", Order = 20)]
    [DataMemberAttribute(Name = "area", Order = 23)]
    public virtual List<AlertInfoArea> Area {
      get {
        return this._area;
      }
      set {
        if ((this._area != null)) {
          if ((_area.Equals(value) != true)) {
            this._area = value;
            this.OnPropertyChanged("Area");
          }
        }
        else {
          this._area = value;
          this.OnPropertyChanged("Area");
        }
      }
    }

    #endregion

  }

}
